package com.unicdata.ai.demo_2af.common.utils;

import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.apache.commons.lang3.StringUtils;

import java.util.Random;
import java.util.regex.Pattern;

/**
 * 密码工具类
 *
 * @author lhn
 * @date 2025/06/25 16:45
 * @since 1.0.0
 **/
public class PasswordUtils {

    /**
     * 加密算法
     */
    public static final String ALGORITHM_NAME = "SHA-256";

    /**
     * 加密次数
     */
    public static final int HASH_ITERATIONS = 1024;

    private static final Pattern COMPLEXITY_PATTERN = Pattern.compile(
            "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[\\W_]).{8,16}$"
    );

    /**
     * 验证密码是否符合复杂度要求
     * 密码不符合安全要求：长度8-16位，包含大小写字母、数字、特殊字符中的至少三种
     * */
    public static boolean isComplexEnough(String password) {
        if (StringUtils.isBlank(password)) return false;

        // 判断是否满足至少三种类型
        int count = 0;
        if (password.matches(".*[a-z].*")) count++;
        if (password.matches(".*[A-Z].*")) count++;
        if (password.matches(".*\\d.*")) count++;
        if (password.matches(".*[\\W_].*")) count++;

        return password.length() >= 8 && password.length() <= 16 && count >= 3;
    }

    /**
     * 生成随机盐
     *
     * @return 随机盐
     */
    public static String generateSalt() {
        Random random = new Random();
        StringBuilder sb = new StringBuilder(16);
        sb.append(random.nextInt(99999999)).append(random.nextInt(99999999));
        int len = sb.length();
        if (len < 16) {
            for (int i = 0; i < 16 - len; i++) {
                sb.append("0");
            }
        }
        return sb.toString();
    }

    /**
     * 加密密码
     *
     * @param password 明文密码
     * @param salt     盐值
     * @return 加密后的密码
     */
    public static String encryptPassword(String password, String salt) {
        if (StringUtils.isBlank(password)) {
            return null;
        }
        ByteSource byteSalt = ByteSource.Util.bytes(salt);
        return new SimpleHash(ALGORITHM_NAME, password, byteSalt, HASH_ITERATIONS).toHex();
    }

    /**
     * 验证密码
     *
     * @param plainPassword 明文密码
     * @param salt          盐值
     * @param encryptedPassword 加密后的密码
     * @return 是否匹配
     */
    public static boolean matches(String plainPassword, String salt, String encryptedPassword) {
        if (StringUtils.isBlank(plainPassword) || StringUtils.isBlank(encryptedPassword) || StringUtils.isBlank(salt)) {
            return false;
        }
        String newPassword = encryptPassword(plainPassword, salt);
        return encryptedPassword.equals(newPassword);
    }

}